/*
 * To change this license header, choose License Headers in Project Properties.
 * To change this template file, choose Tools | Templates
 * and open the template in the editor.
 */

package privatewhiteboard.client;

import java.awt.*;
import java.awt.event.*;
import java.rmi.RemoteException;
import java.util.*;
import java.util.logging.Level;
import java.util.logging.Logger;
import javax.swing.*;
import javax.swing.plaf.basic.BasicSplitPaneUI;
import javax.swing.plaf.basic.BasicTabbedPaneUI;
import privatewhiteboard.shared.controllers.IClientController;
import privatewhiteboard.shared.interfaces.IChatBoard;

/**
 *
 * @author Sherry
 */
public class ChatBoardPanel extends JPanel implements IChatBoard 
{
    IClientController _clientController;
    boolean isEmoTabbedPaneVisible = false;
    EmoTabbedPane emoTabbedPane;
    
    private static ArrayList<Message> _messageList = new ArrayList<Message>();
    
    /**
     * Creates new form ChatBoardPanel
     */
    public ChatBoardPanel() 
    {
        EmoticonLibrary.Initialize();
        emoTabbedPane = new EmoTabbedPane(this);
        initComponents();
    }
    
    public void Initialize(IClientController clientController)
    {
        _clientController = clientController;
    }

    /**
     * This method is called from within the constructor to initialize the form.
     * WARNING: Do NOT modify this code. The content of this method is always
     * regenerated by the Form Editor.
     */
    /*
    @SuppressWarnings("unchecked")
    // <editor-fold defaultstate="collapsed" desc="Generated Code">//GEN-BEGIN:initComponents
    private void initComponents() {

        scrollPaneConversation = new javax.swing.JScrollPane();
        Conversation = new javax.swing.JEditorPane();
        messPanel = new javax.swing.JPanel();
        labelEmo = new javax.swing.JLabel();
        jScrollPane1 = new javax.swing.JScrollPane();
        Message = new javax.swing.JTextArea();

        setMaximumSize(new java.awt.Dimension(300, 600));
        setMinimumSize(new java.awt.Dimension(300, 600));
        setPreferredSize(new java.awt.Dimension(300, 600));

        Conversation.setEditable(false);
        Conversation.setContentType("text/html"); // NOI18N
        Conversation.setCursor(new java.awt.Cursor(java.awt.Cursor.DEFAULT_CURSOR));
        Conversation.setMaximumSize(new java.awt.Dimension(280, 535));
        Conversation.setMinimumSize(new java.awt.Dimension(280, 535));
        Conversation.setPreferredSize(new java.awt.Dimension(280, 535));
        scrollPaneConversation.setViewportView(Conversation);

        add(scrollPaneConversation);

        messPanel.setMaximumSize(new java.awt.Dimension(280, 40));
        messPanel.setMinimumSize(new java.awt.Dimension(280, 40));
        messPanel.setPreferredSize(new java.awt.Dimension(280, 40));

        labelEmo.setIcon(new javax.swing.ImageIcon(getClass().getResource("/Images/btnFace.png"))); // NOI18N
        labelEmo.addMouseListener(new java.awt.event.MouseAdapter() {
            public void mouseClicked(java.awt.event.MouseEvent evt) {
                labelEmoMouseClicked(evt);
            }
        });
        messPanel.add(labelEmo);

        Message.setColumns(20);
        Message.setRows(2);
        Message.addKeyListener(new java.awt.event.KeyAdapter() {
            public void keyPressed(java.awt.event.KeyEvent evt) {
                MessageKeyPressed(evt);
            }
            public void keyReleased(java.awt.event.KeyEvent evt) {
                MessageKeyReleased(evt);
            }
        });
        jScrollPane1.setViewportView(Message);

        messPanel.add(jScrollPane1);

        add(messPanel);
    }// </editor-fold>//GEN-END:initComponents
    */
    
    private void initComponents() 
    {
        scrollPaneConversation = new JScrollPane();
        Conversation = new JEditorPane();
        messPanel = new JPanel();
        Message = new JTextArea();
        labelEmo = new JLabel();

        setLayout(new BorderLayout());

        Conversation.setEditable(false);
        Conversation.setContentType("text/html"); // NOI18N
        Conversation.setBackground(new Color(185, 229, 251));
        scrollPaneConversation.setHorizontalScrollBarPolicy(JScrollPane.HORIZONTAL_SCROLLBAR_NEVER);
        scrollPaneConversation.setViewportView(Conversation);
        scrollPaneConversation.setAutoscrolls(true);
        //scrollPaneConversation.getVerticalScrollBar().setValue(scrollPaneConversation.getVerticalScrollBar().getMaximum());

        add(scrollPaneConversation, BorderLayout.CENTER);

        Message.setAutoscrolls(true);
        Message.setLineWrap(true);
        Message.setBorder(javax.swing.BorderFactory.createLineBorder(new Color(102, 153, 255)));
        Message.setFont(new Font("Times New Roman", 0, 13)); // NOI18N
        Message.setText("");
        //Message.grabFocus();
        //Message.setMaximumSize(new java.awt.Dimension(245, 60));
        Message.setMinimumSize(new Dimension(245, 40));
        Message.setPreferredSize(new Dimension(245, 40));
        Message.addKeyListener(new KeyAdapter() 
        {
            public void keyPressed(KeyEvent evt) 
            {
                MessageKeyPressed(evt);
            }
            public void keyReleased(KeyEvent evt) 
            {
                MessageKeyReleased(evt);
            }
        });
        Message.getAccessibleContext().setAccessibleDescription("text/plain");
        Message.getAccessibleContext().setAccessibleParent(messPanel);
        Message.setRows(2);

        labelEmo.setIcon(new javax.swing.ImageIcon(getClass().getResource("/Images/btnFace.png"))); // NOI18N
        labelEmo.addMouseListener(new java.awt.event.MouseAdapter() 
        {
            public void mouseClicked(java.awt.event.MouseEvent evt) 
            {
                labelEmoMouseClicked(evt);
            }
        });
        messPanel.add(Message);
        messPanel.add(labelEmo);

        add(messPanel, BorderLayout.PAGE_END);
    }
    
    private void labelEmoMouseClicked(java.awt.event.MouseEvent evt) {//GEN-FIRST:event_labelEmoMouseClicked
        emoTabbedPane.setLocationRelativeTo(labelEmo);
        emoTabbedPane.setSize(300, 361);
        emoTabbedPane.setResizable(false);
        emoTabbedPane.setLocation(emoTabbedPane.getX(), emoTabbedPane.getY() - 340);
        emoTabbedPane.setAlwaysOnTop(true);
        if(isEmoTabbedPaneVisible == false)
        {
            emoTabbedPane.setLocationRelativeTo(labelEmo);
            emoTabbedPane.setVisible(true);
            isEmoTabbedPaneVisible = true;
        }
        else
        {
            emoTabbedPane.setVisible(false);
            isEmoTabbedPaneVisible = false;
        }
    }//GEN-LAST:event_labelEmoMouseClicked

    private void MessageKeyPressed(java.awt.event.KeyEvent evt) {//GEN-FIRST:event_MessageKeyPressed
        if(evt.getKeyCode() == KeyEvent.VK_ENTER && !Message.getText().equals(""))
        {
            try {
                AddMessage("You", new Date(), Message.getText());
                if(_clientController != null)
                _clientController.BoardcastMessage(Message.getText());
                else
                System.out.println("Can't not broadcast to server because ClientController has not been initialized");
                //Message.setText("");
            } catch (RemoteException e)
            {
                e.printStackTrace();
            }
        }
    }//GEN-LAST:event_MessageKeyPressed

    private void MessageKeyReleased(java.awt.event.KeyEvent evt) {//GEN-FIRST:event_MessageKeyReleased
        if(evt.getKeyCode() == KeyEvent.VK_ENTER)
            Message.setText("");
    }//GEN-LAST:event_MessageKeyReleased

    // Variables declaration - do not modify//GEN-BEGIN:variables
    private javax.swing.JEditorPane Conversation;
    private javax.swing.JTextArea Message;
    private javax.swing.JScrollPane jScrollPane1;
    private javax.swing.JLabel labelEmo;
    private javax.swing.JPanel messPanel;
    private javax.swing.JScrollPane scrollPaneConversation;
    // End of variables declaration//GEN-END:variables
    
    @Override
    public void PostMessage(int messageId, String senderName, Date sentTime, String messageContent) throws RemoteException 
    {
            AddMessage(senderName, sentTime, messageContent);
    }

    @Override
    public void PostEmotion(int messageId, String senderName, Date sentTime, String emotionId) throws RemoteException 
    {
        AddEmoticon(senderName, sentTime, Integer.parseInt(emotionId));
    }
    
    public void BroadcastEmoticon(int emoId) throws RemoteException
    {
        AddEmoticon("You", new Date(), emoId);
        if(_clientController != null)
            _clientController.BoardcastEmotion(Integer.toString(emoId));
    }
    
    public void AddMessage(String sender, Date time, String content)
    {
        String htmlContent = "<b>" + sender + " (" + time.toLocaleString() + ") :</b><br>" + WrapText(content, _numOfCharToBreakLine) + "<br>";
        Message message = new Message(sender, time, htmlContent);
        _messageList.add(message);
        RefreshChatBoard();
    }
    
    public void AddEmoticon(String sender, Date time, int emoticonId)
    {
        String htmlContent = "<b>" + sender + " (" + time.toLocaleString() + ") :</b><br>" + "<img src='" + ClassLoader.getSystemResource(EmoticonLibrary.IdToPath.get(emoticonId)) + "'></img><br>";
        Message message = new Message(sender, time, htmlContent);
        _messageList.add(message);
        RefreshChatBoard();
    }
    
    public void RefreshChatBoard()
    {
        String htmlContent = "<html><table style='width: 300px;'><tr><td style='width: 300px'>";
        for(int i=0; i<_messageList.size(); i++)
        {
            htmlContent += _messageList.get(i).GetHtmlContent();
        }
        htmlContent += "</td></tr></table></html>";
        Conversation.setText(htmlContent);   
    }
    int _numOfCharToBreakLine = 40;
    public String WrapText(String source, int numOfCharToBreakLine)
    {
        StringBuilder result = new StringBuilder();
        int currentIndex = 0;
        while(currentIndex < source.length())
        {
            if(currentIndex + numOfCharToBreakLine < source.length())
            {
                int endIndex = currentIndex + numOfCharToBreakLine;
                while(true)
                {
                    if(endIndex <= currentIndex)//DK dung` 1
                    {
                        endIndex = currentIndex + numOfCharToBreakLine;
                        break;
                    }
                    if(source.charAt(endIndex) == ' ')
                    {
                        break;
                    }
                    endIndex--;
                }
                result.append(source.substring(currentIndex, endIndex)).append("<br>");
                currentIndex = endIndex + 1;
            }
            else
            {
                result.append(source.substring(currentIndex, source.length())).append("<br>");
                currentIndex = source.length();//to finish
            }
        }
        return result.toString();
    }
}
